package com.handinfo.engine;

import javax.microedition.lcdui.Graphics;

import com.handinfo.game.GameScene;
import com.handinfo.util.Tools;
import com.xl.lib.Utils;

import java.io.*;

/**
 * <p>
 * Title: MMO1
 * </p>
 * 
 * <p>
 * Description: MMO1
 * </p>
 * 
 * <p>
 * Copyright: Copyright (c) 2009
 * </p>
 * 
 * <p>
 * Company: HandInfo
 * </p>
 * 
 * @author Xia Mingwei
 * @version 1.0
 */
public abstract class AbstractGameScript
{
	public AbstractGameScene m_scene;

	public AbstractGameScript(AbstractGameScene scene)
	{
		m_scene = scene;
	}

	// 游戏世界全局变量
	public static int s_vars[];

	/**
	 * 从事件引擎数据文件中读取所有变量的初值
	 */
	public static void initVariable()
	{
		try {
			DataInputStream dis = new DataInputStream(
//					AbstractGameScreen.FILE_EVENTENGINE.getClass()
					Utils
							.getResourceAsStream(
									AbstractGameScreen.FILE_EVENTENGINE
											+ ".bin"));
			int varCount = dis.readShort();
			s_vars = new int[varCount];
			for (int i = 0; i < varCount; i++) {
				s_vars[i] = dis.readShort();
			}
		}
		catch (IOException ex) {
			Tools.debug(ex);
		}
	}

	// //////////////////////////////////////////////////////////////////////////
	// // 实时过场动画引擎代码块开始……
	public final static int THREAD_ACTOR_ID = 0; // Actor ID
	public final static int THREAD_ACTOR_ID_FLAG_SKIP = (1 << 15);
	public final static int KEYFRAME_DATA_BEGIN = 1;
	public final static int KEYFRAME_DATA_SIZE = 5;

	public final static int KEYFRAME_FRAME = 0;
	public final static int KEYFRAME_X = 1;
	public final static int KEYFRAME_Y = 2;
	public final static int KEYFRAME_ACTION_AND_FLAG = 3; // 元件动作ID以及标志位

	public final static int KEYFRAME_MASK_ACTION = 0x0FFF; // 动作ID的mask
	public final static int KEYFRAME_MASK_FLAG_HIDE = 0x8000; // 标志位的mask
	public final static int KEYFRAME_MASK_FLAG_DELETEME = 0x4000;
	public final static int KEYFRAME_MASK_FLAG_FLIPX = 0x2000;
	public final static int KEYFRAME_MASK_FLAG_FLIPY = 0x1000;
	public final static int KEYFRAME_COMMAND = 4; // 系统指令ID

	public short[][][] m_trailerData; // 场景中所有实时过场动画数据
	public short[][] m_curTrailer; // 当前触发的过场动画数据
	public short[][] m_trailerActionData; // 过场动画包含的动作数据
	public int m_curTrailerFrameId = -1; // 当前过场动画所在帧
	public boolean m_trailerEnd = true; // 过场动画是否执行完毕
	public int m_curTrailerId = -1; //当前过场动画ID

	public void loadTrailerData(DataInputStream dis) throws IOException
	{
		int count;
		// UI.drawLoading(45);
		// 载入过场动画数据
		count = dis.readByte(); // 过场动画数量
		m_trailerData = new short[count][][];
		for (int i = 0; i < count; i++) {
			int actorNum = dis.readUnsignedByte();
			m_trailerData[i] = new short[actorNum][];
			for (int j = 0; j < actorNum; j++) {
				int size = (dis.readShort() >> 1);
				m_trailerData[i][j] = new short[size];
				for (int n = 0; n < size; n++) {
					m_trailerData[i][j][n] = dis.readShort();
				}
			}
		}
		// UI.drawLoading(47);
		// 载入过场动画的指令数据
		m_trailerActionData = new short[count][];
		for (int i = 0; i < count; i++) {
			int size = dis.readShort() >> 1;
			m_trailerActionData[i] = new short[size];
			for (int j = 0; j < size; j++) {
				m_trailerActionData[i][j] = dis.readShort();
			}
		}
		// UI.drawLoading(50);
		// 载入场景触发器数据
		count = dis.readShort(); // 触发器数量
		// System.out.println("event count: " + count);
		// 触发器数据分成两份，一份是触发事件列表，一份为触发器实体数据
		m_triggerEventList = new byte[count][];
		m_triggerData = new short[count][];
		for (int i = 0; i < count; i++) {
			// 载入事件列表
			int size = dis.readByte(); // 监听事件数
			m_triggerEventList[i] = new byte[size];
			for (int j = 0; j < size; j++) {
				m_triggerEventList[i][j] = dis.readByte();
			}
			// 载入触发器实体数据
			size = dis.readShort() >> 1;
			m_triggerData[i] = new short[size];
			for (int j = 0; j < size; j++) {
				m_triggerData[i][j] = dis.readShort();
			}
		}
		// UI.drawLoading(65);
	}

	/**
	 * 过场动画逐帧播放
	 * 
	 * @param trailerId
	 * 过场动画ID
	 */
	public void runTrailer(boolean trailerMode, int trailerId)
	{
		Graphics g = GameManager.getInstance().m_screen.getGraphics();
		long tick;
		m_curTrailer = m_trailerData[trailerId];
		m_curTrailerFrameId = 0;
		m_trailerEnd = false;
		m_scene.m_oldFocusActor = m_scene.m_focusActor;
		initTrailer(m_curTrailer); // 初始化过场动画数据
		initTrigger();
		m_curTriggerData = m_trailerActionData[trailerId]; // 过场动画动作数据
		m_curDataIndex = 1; // 跳过动作个数
		if (trailerMode) {
			beginTrailer(g); // 开启过场动画遮幅
		}
		while (!m_trailerEnd) {
			tick = System.currentTimeMillis() + GameManager.FRAME_INTERVAL;
			updateTrailer(m_curTrailer, m_curTrailerFrameId++);
			// 设置动画元件为不可见
			m_curTrailer[0][THREAD_ACTOR_ID] &= ~THREAD_ACTOR_ID_FLAG_SKIP;
			Actor actor = (Actor) (m_scene.m_static_actors
					.elementAt(m_curTrailer[0][THREAD_ACTOR_ID]));
			actor.setEnabled(false);

			m_scene.updateTrailer();
			
			GameManager.getInstance().keepConnectionAlive();
			GameManager.getInstance().m_screen.flush();
			while (tick > System.currentTimeMillis()) {
				Thread.yield();
			}
		}
		if (trailerMode) {
			endTrailer(g); // 关闭过场动画遮幅
		}
		endTrigger();
		m_trailerEnd = true;
		m_curTrailerId = -1;
		m_scene.m_focusActor = m_scene.m_oldFocusActor;
		m_scene.m_smoothCamera = true;
		GameManager.getInstance().m_game_message.sendEndTrailer();
		AbstractGameScreen.updateKeyEnd();
	}

	/**
	 * 初始化过场动画，主要是初始帧的位置需要设置为当前元件位置而不是初始数据
	 * 
	 * @param trailer
	 * 过场动画数据
	 */
	public void initTrailer(short[][] trailer)
	{
		// beginInitTrailer(s_canvas.getGraphics());
		for (int i = 0; i < trailer.length; i++) {
			trailer[i][THREAD_ACTOR_ID] &= ~THREAD_ACTOR_ID_FLAG_SKIP;
			Actor actor = (Actor) (m_scene.m_static_actors
					.elementAt(trailer[i][THREAD_ACTOR_ID]));
			if ((actor.m_flag & Actor.ACTOR_FLAG_SELF) != 0) {
				actor = ((GameScene) m_scene).m_controlledActor;
			}
			// if (i == 0) {
			// m_scene.setFocusActor(actor); // 设置摄像机元件
			// }
			// 设置过场参与元件的起始帧位置为当前所在位置，避免产生被拉扯过去的效果
			// trailer[i][KEYFRAME_DATA_BEGIN + KEYFRAME_X] = (short)
			// actor.m_posX;
			// trailer[i][KEYFRAME_DATA_BEGIN + KEYFRAME_Y] = (short)
			// actor.m_posY;
			// 当设置的位置参数都为-1的时候，该actor保持当前位置不动
			if (trailer[i][KEYFRAME_DATA_BEGIN + KEYFRAME_X] != -1
					|| trailer[i][KEYFRAME_DATA_BEGIN + KEYFRAME_X] != -1) {
				actor.m_posX = trailer[i][KEYFRAME_DATA_BEGIN + KEYFRAME_X];
				actor.m_posY = trailer[i][KEYFRAME_DATA_BEGIN + KEYFRAME_Y];
			}
			actor.setAction(trailer[i][KEYFRAME_DATA_BEGIN
					+ KEYFRAME_ACTION_AND_FLAG] & 0x0fff, true);
			// 自定义代码区
		}
		m_scene.draw(GameManager.getInstance().m_screen.getGraphics());
		GameManager.getInstance().m_screen.flush();
		// endInitTrailer(s_canvas.getGraphics());
	}

	public final static int TRAILER_HEIGHT = 8;

	/**
	 * 过场动画开始时黑幕放下
	 * 
	 * @param g
	 */
	public void beginTrailer(Graphics g)
	{
		m_scene.m_trailerModeHeight = 0;
		while (m_scene.m_trailerModeHeight < m_scene.m_cameraH / TRAILER_HEIGHT) {
			m_scene.m_trailerModeHeight += 2;
			if (m_scene.m_trailerModeHeight > m_scene.m_cameraH
					/ TRAILER_HEIGHT) {
				m_scene.m_trailerModeHeight = m_scene.m_cameraH
						/ TRAILER_HEIGHT;
			}
			m_scene.updateTrailer();
//			m_scene.draw(g);
//			m_scene.drawTrailerMode(g);
			GameManager.getInstance().m_screen.flush();
			GameManager.waitAnyTime(60);
		}
	}

	/**
	 * 过场动画结束时黑幕撤去
	 * 
	 * @param g
	 */
	public void endTrailer(Graphics g)
	{
		while (m_scene.m_trailerModeHeight > 0) {
			m_scene.m_trailerModeHeight -= 2;
			if (m_scene.m_trailerModeHeight < 0) {
				m_scene.m_trailerModeHeight = 0;
			}
			m_scene.updateTrailer();
//			m_scene.draw(g);
//			m_scene.drawTrailerMode(g);
			GameManager.getInstance().m_screen.flush();
			GameManager.waitAnyTime(60);
		}
	}

	/**
	 * 过场动画状态更新
	 */
	public void updateTrailer(short[][] trailer, int frame)
	{
		if (m_scene.m_bg != null) {
			m_scene.m_bg.tick();
		}
		for (int i = 0; i < trailer.length; i++) {
			updateTrailerActor(trailer[i], frame, i == 0);
		}
	}

	/**
	 * 过场动画参与元件的状态更新
	 * 
	 * @param thread
	 * 元件每帧数据
	 * @param frame
	 * 帧
	 * @param isCamera
	 * 是否是摄像头元件
	 */
	public void updateTrailerActor(short[] thread, int frame, boolean isCamera)
	{
		if ((thread[THREAD_ACTOR_ID] & THREAD_ACTOR_ID_FLAG_SKIP) != 0) {
			return;
		}
		Actor actor = (Actor) (m_scene.m_static_actors
				.elementAt(thread[THREAD_ACTOR_ID]));
		if ((actor.m_flag & Actor.ACTOR_FLAG_SELF) != 0) {
			actor = ((GameScene) m_scene).m_controlledActor;
		}
		int keyframe = -1;
		int nextkeyframe = -1;
		// 循环关键帧数据获得当前关键帧和下一个关键帧
		for (int k = KEYFRAME_DATA_BEGIN; k < thread.length; k += KEYFRAME_DATA_SIZE) {
			if (frame < thread[k + KEYFRAME_FRAME]) {
				nextkeyframe = k;
				break;
			}
			keyframe = k;
		}
		short keyframe_flag = thread[keyframe + KEYFRAME_ACTION_AND_FLAG];
		if ((keyframe_flag & KEYFRAME_MASK_FLAG_DELETEME) != 0) {
			actor.m_enabled = false;
		}
		else {
			actor.m_enabled = true;
		}
		if ((keyframe_flag & KEYFRAME_MASK_FLAG_HIDE) != 0) {
			actor.m_visible = false;
		}
		else {
			actor.m_visible = true;
			actor.m_needDraw = true;
		}
		if ((keyframe_flag & KEYFRAME_MASK_FLAG_FLIPX) != 0) {
			actor.m_flipX = true;
		}
		else {
			actor.m_flipX = false;
		}
		if ((keyframe_flag & KEYFRAME_MASK_FLAG_FLIPY) != 0) {
			actor.m_flipY = true;
		}
		else {
			actor.m_flipY = false;
		}
		int posX = actor.m_posX;
		int posY = actor.m_posY;
		// 计算出过场中元件在当前帧的位置
		if (nextkeyframe > 0) {
			if (thread[nextkeyframe + KEYFRAME_X] != -1
					|| thread[nextkeyframe + KEYFRAME_Y] != -1) {
				posX += (((thread[nextkeyframe + KEYFRAME_X] - posX)) / (thread[nextkeyframe
						+ KEYFRAME_FRAME] - frame));
				posY += (((thread[nextkeyframe + KEYFRAME_Y] - posY)) / (thread[nextkeyframe
						+ KEYFRAME_FRAME] - frame));
			}
		}
		int actionId = thread[keyframe + KEYFRAME_ACTION_AND_FLAG]
				& KEYFRAME_MASK_ACTION;
		int frameId = frame - thread[keyframe + KEYFRAME_FRAME];
		actor.setActionFrame(actionId, frameId);
		actor.m_posX = posX;
		actor.m_posY = posY;
		actor.m_vX = 0;
		actor.m_vY = 0;
		/**
		 * 处理过场动画执行过程中的动作
		 */
		int command = thread[keyframe + KEYFRAME_COMMAND];
		int commandId;
		if (command > -1 && frame == thread[keyframe + KEYFRAME_FRAME]) { // 如果该帧有动作
//			size = m_curTriggerData[m_curDataIndex++];
			commandId = m_curTriggerData[m_curDataIndex++];
			executeAction(commandId);
		}
		if (isCamera) {
			if (nextkeyframe < 0) {
				m_trailerEnd = true;
			}
			else {
				if (thread[nextkeyframe + KEYFRAME_FRAME]
						- thread[keyframe + KEYFRAME_FRAME] <= 1) {
					m_scene.m_bg.m_updateBg = true;
				}
			}
		}
	}

	// // 实时过场动画引擎代码块结束
	// //////////////////////////////////////////////////////////////////////////

	// //////////////////////////////////////////////////////////////////////////
	// // 事件触发引擎代码块开始
	public final static int COND_FINAL = 0; // 条件表达式
	public final static int COND_AND = 1; // 和条件组
	public final static int COND_OR = 2; // 或条件组
	public final static int TYPE_NUMBER = 0; // 数值
	public final static int TYPE_FUNCTION = 1; // 功能
	public final static int TYPE_VARIABLE = 2; // 变量
	public final static int TYPE_CONDITION = 3; // 条件
	public final static int TYPE_ACTION = 4; // 动作
	public final static int TYPE_OPERATOR = 5; // 操作符
	public final static int OP_EQ = 0; // 等于
	public final static int OP_NE = 1; // 不等于
	public final static int OP_LT = 2; // 小于
	public final static int OP_GT = 3; // 大于
	public final static int OP_LE = 4; // 小于等于
	public final static int OP_GE = 5; // 大于等于
	public final static int COM_PLUS = 0; // 加
	public final static int COM_MINUS = 1; // 减
	public final static int COM_MULTI = 2; // 乘
	public final static int COM_DIVIDE = 3; // 除
	public byte[][] m_triggerEventList; // 触发器监听的事件列表
	public short[][] m_triggerData; // 所有触发器数据
	public short[] m_curTriggerData; // 当前触发器数据
	public int m_curDataIndex; // 当前触发器数据索引
	public boolean m_triggerEnd = true; // 触发器是否执行完毕
	public short[][] m_recursionTriggerData = new short[8][]; // 递归数据
	public int[] m_recursionDataIndex = new int[8]; // 递归数据索引
	public byte m_recursionLevel = 0; // 递归层级
	/**
	 * 触发事件 当事件触发时，遍历场景中的所有触发器，检查是否有触发器监听此事件，如果有则执行触 发器的内容
	 * 
	 * @param eventId
	 * 事件ID
	 */
	int preEventId = -1;

	public void fireEvent(int eventId)
	{
		if (m_triggerEventList == null) { // 场景中不存在触发器
			return;
		}
		for (int i = 0; i < m_triggerEventList.length; i++) {
			for (int j = 0; j < m_triggerEventList[i].length; j++) {
				// 如果有触发器监听此事件则执行触发器
				// System.out.println("m_triggerEventList: "+m_triggerEventList[i][j]);
				if (eventId == m_triggerEventList[i][j]) {
					if (eventId != preEventId) {
						preEventId = eventId;
						// System.out.println("fire event: " +
						// getEventName(eventId));
					}
					initTrigger();
					m_curTriggerData = m_triggerData[i]; // 获得触发器ID
					m_curDataIndex = 0;
					m_triggerEnd = false;
					runTrigger();
					endTrigger();
				}
			}
		}
	}

	/**
	 * 初始化触发器 主要是进行递归的设置
	 */
	public void initTrigger()
	{
		m_recursionTriggerData[m_recursionLevel] = m_curTriggerData;
		m_recursionDataIndex[m_recursionLevel] = m_curDataIndex;
		m_recursionLevel++;
	}

	/**
	 * 结束触发器执行 跳回递归上一层
	 */
	public void endTrigger()
	{
		m_recursionLevel--;
		m_curTriggerData = m_recursionTriggerData[m_recursionLevel];
		m_curDataIndex = m_recursionDataIndex[m_recursionLevel];
	}

	/**
	 * 执行触发器 先检查触发器条件是否满足，然后遍历执行动作
	 */
	public void runTrigger()
	{
		boolean canTrigger = getCondition();
		if (!canTrigger) {
			return;
		}
		int actionCount = m_curTriggerData[m_curDataIndex++];
		int i = 0, actionId;
		// if (actionCount > 0) {
		// m_scene.m_player.m_vX = 0;
		// m_scene.m_player.m_vY = 0;
		// }
		while (i < actionCount && !m_triggerEnd) {
//			size = m_curTriggerData[m_curDataIndex++];
			actionId = m_curTriggerData[m_curDataIndex++];
			executeAction(actionId);
			i++;
		}
	}

	/**
	 * 从触发器数据中获得条件值
	 * 
	 * @return
	 */
	public boolean getCondition()
	{
		boolean result = true;
		int condType = getShort(); // 条件类型
		if (condType == COND_FINAL) { // 如果不是条件组
			int leftValue = getParameter();
			int operator = getShort();
			int rightValue = getParameter();
			switch (operator) {
				case OP_EQ: { // ==
					if (leftValue == rightValue) {
						result = true;
					}
					else {
						result = false;
					}
					break;
				}
				case OP_NE: { // !=
					if (leftValue != rightValue) {
						result = true;
					}
					else {
						result = false;
					}
					break;
				}
				case OP_LT: { // <
					if (leftValue < rightValue) {
						result = true;
					}
					else {
						result = false;
					}
					break;
				}
				case OP_GT: { // >
					if (leftValue > rightValue) {
						result = true;
					}
					else {
						result = false;
					}
					break;
				}
				case OP_LE: { // <=
					if (leftValue <= rightValue) {
						result = true;
					}
					else {
						result = false;
					}
					break;
				}
				case OP_GE: { // >=
					if (leftValue >= rightValue) {
						result = true;
					}
					else {
						result = false;
					}
					break;
				}
				default: {
					result = false;
				}
			}
		}
		else { // 是条件组
			if (condType == COND_AND) { // 和的条件组
				result = true;
				int size = getShort();
				for (int i = 0; i < size; i++) {
					if (getCondition() == false) {
						result = false;
					}
				}
			}
			else { // 或的条件组
				result = false;
				int size = getShort();
				for (int i = 0; i < size; i++) {
					if (getCondition() == true) {
						result = true;
					}
				}
			}
		}
		return result;
	}

	/**
	 * 从触发器数据中获得一个数值
	 * 
	 * @return
	 */
	public int getShort()
	{
		return m_curTriggerData[m_curDataIndex++];
	}

	/**
	 * 布尔参数
	 * 
	 * @return boolean
	 */
	public boolean getBooleanParam()
	{
		return getParameter() == 1;
	}

	/**
	 * 获得参数最终值的方法 参数类型会对给定值进行处理返回的才是最终值
	 * 
	 * @param type
	 * 参数类型
	 * @param result
	 * 参数的给定值
	 * @return
	 */
	public int getParameterValue(int type, int result)
	{
		switch (type) {
			case TYPE_VARIABLE: {
				return s_vars[result];
			}
			case TYPE_FUNCTION: {
				return getFunctionValue(result);
			}
		}
		return result;
	}

	/**
	 * 从触发器数据中获得参数最终值
	 * 
	 * @return
	 */
	public int getParameter()
	{
		int type = getShort();
		int value = getShort();
		return getParameterValue(type, value);
	}

	/**
	 * 设置命令的变量值
	 * 
	 * @param value
	 * int
	 */
	public void setVariable(int value)
	{
		int type = getShort();
		if (Tools.DEBUG) {
			if (type != TYPE_VARIABLE) {
				System.err.println("参数错误,指定参数不是变量 #" + type);
			}
		}
		s_vars[getShort()] = value;
	}

	// // 事件触发引擎代码块
	// //////////////////////////////////////////////////////////////////////////

	/**
	 * 功能定义需要用到的变量
	 */
	public int m_eventActorClass = -1; // 触发事件的元件定义
	public int m_eventActorId = -1; // 触发事件的元件ID
	public int m_eventActorAction = -1; // 触发事件的元件动作
	public int m_collideActorClass = -1; // 被碰撞的元件定义
	public int m_collideActorId = -1; // 被碰撞的元件ID
	public int m_collideActorAction = -1; // 被碰撞的元件动作
	public int m_activateActorClass = -1; // 激活判定的元件定义
	public int m_activateActorId = -1; // 激活判定的元件ID
	public int m_activateActorAction = -1; // 激活判定的元件动作

	/**
	 * 设置事件相关Actor的信息
	 * 
	 * @param actorClass
	 * int
	 * @param actorId
	 * int
	 * @param actorAction
	 * int
	 */
	public void setEventActorInfo(int actorClass, int actorId, int actorAction)
	{
		m_eventActorClass = actorClass;
		m_eventActorId = actorId;
		m_eventActorAction = actorAction;
	}

	public void setCollideActorInfo(int actorClass, int actorId, int actorAction)
	{
		m_collideActorClass = actorClass;
		m_collideActorId = actorId;
		m_collideActorAction = actorAction;
	}

	public void setActiveActorInfo(int actorClass, int actorId, int actorAction)
	{
		m_activateActorClass = actorClass;
		m_activateActorId = actorId;
		m_activateActorAction = actorAction;
	}

	/**
	 * 跳过触发器数据 很多情况下均需要跳过数据，比如执行动作时某个条件不满足时需要跳过当前的动作 又比如当动作是参数时有可能要跳过该动作不执行
	 */
	public void skip(int size)
	{
		m_curDataIndex += size;
	}

	/**
	 * 跳过动作参数
	 */
	public void skipAction()
	{
		getShort(); // 跳过动作类型参数的标识
		int count = getShort();
		int size = 0;
		for (int i = 0; i < count; i++) {
			size = getShort() >> 1;
			skip(size);
		}
	}

	/**
	 * 计算变量a值
	 * 
	 * @param leftValue
	 * 左值
	 * @param operator
	 * 运算符
	 * @param rightValue
	 * 右值
	 * @return
	 */
	public int computeVariable(int leftValue, int operator, int rightValue)
	{
		switch (operator) {
			case COM_PLUS: { // 加
				return leftValue + rightValue;
			}
			case COM_MINUS: { // 减
				return leftValue - rightValue;
			}
			case COM_MULTI: { // 乘
				return leftValue * rightValue;
			}
			case COM_DIVIDE: { // 除
				return leftValue / rightValue;
			}
			default: { // 默认为加法
				return leftValue + rightValue;
			}
		}
	}

	/**
	 * 执行动作，动作在工具层面定义，但具体执行每款游戏需要单独实现 getShort()来获得参数类型或参数值
	 * getParameter()来直接获得参数值，将获得参数类型和通过类型解析值合二为一
	 * getCondition()来获得条件参数的结果，递归调用executeAction()方法来执行动作参数
	 * 调用skip()来跳过一段触发器数据，调用skipAction()来跳过动作参数
	 * 
	 * @param actionId
	 * 动作ID
	 */
	public abstract void executeAction(int actionId);

	public abstract String getEventName(int eventId);

	public abstract String getActionName(int actionId);

	public abstract int getFunctionValue(int functionId);

	public void dispose()
	{
		int i;
		m_scene = null;

		if (m_trailerData != null) {
			for (i = 0; i < m_trailerData.length; i++) {
				if (m_trailerData[i] != null) {
					for (int j = 0; j < m_trailerData[i].length; j++) {
						m_trailerData[i][j] = null;
					}
					m_trailerData[i] = null;
				}
			}
			m_trailerData = null;
		}
		if (m_curTrailer != null) {
			for (i = 0; i < m_curTrailer.length; i++) {
				m_curTrailer[i] = null;
			}
			m_curTrailer = null;
		}
		if (m_trailerActionData != null) {
			for (i = 0; i < m_trailerActionData.length; i++) {
				m_trailerActionData[i] = null;
			}
		}
		// UI.drawLoading(8);

		if (m_triggerEventList != null) {
			for (i = 0; i < m_triggerEventList.length; i++) {
				m_triggerEventList[i] = null;
			}
			m_triggerEventList = null;
		}
		if (m_triggerData != null) {
			for (i = 0; i < m_triggerData.length; i++) {
				m_triggerData[i] = null;
			}
			m_triggerData = null;
		}
		m_curTriggerData = null;
		if (m_recursionTriggerData != null) {
			for (i = 0; i < m_recursionTriggerData.length; i++) {
				m_recursionTriggerData[i] = null;
			}
			m_recursionTriggerData = null;
		}
		m_recursionDataIndex = null;
		// UI.drawLoading(10);
	}

	   public static final int EVENT_SCENE_INIT = 0;
	   public static final int EVENT_SCENE_LOADED = 1;
	   public static final int EVENT_SCENE_UNLOADED = 2;
	   public static final int EVENT_TICK_EVENT = 3;
	   public static final int EVENT_COLLIDE_PLAYER = 4;
	   public static final int EVENT_ACTIVATE_PLAYER = 5;
	   public static final int EVENT_COLLIDE_ACTOR = 6;
	   public static final int EVENT_ACTIVATE_ACTOR = 7;
	   public static final int EVENT_KEY_PRESSED = 8;
	   public static final int EVENT_ACTOR_ACTIONOVER = 9;
	   public static final int EVENT_ACTOR_HIDE = 10;
	   public static final int EVENT_ACTOR_DELETE = 11;

	   public static final int FUN_RUN_FRAME = 0;
	   public static final int FUN_EVENT_ACTORCLASS = 1;
	   public static final int FUN_EVENT_ACTORID = 2;
	   public static final int FUN_EVENT_ACTORACTION = 3;
	   public static final int FUN_COLLIDE_ACTORCLASS = 4;
	   public static final int FUN_COLLIDE_ACTORID = 5;
	   public static final int FUN_COLLIDE_ACTORACTION = 6;
	   public static final int FUN_ACTIVATE_ACTORCLASS = 7;
	   public static final int FUN_ACTIVATE_ACTORID = 8;
	   public static final int FUN_ACTIVATE_ACTORACTION = 9;
	   public static final int FUN_UP_PRESSED = 10;
	   public static final int FUN_UPRIGHT_PRESSED = 11;
	   public static final int FUN_RIGHT_PRESSED = 12;
	   public static final int FUN_DOWNRIGHT_PRESSED = 13;
	   public static final int FUN_DOWN_PRESSED = 14;
	   public static final int FUN_DOWNLEFT_PRESSED = 15;
	   public static final int FUN_LEFT_PRESSED = 16;
	   public static final int FUN_UPLEFT_PRESSED = 17;
	   public static final int FUN_CONFIRM_PRESSED = 18;
	   public static final int FUN_POUND_PRESSED = 19;
	   public static final int FUN_ZERO_PRESSED = 20;
	   public static final int FUN_STAR_PRESSED = 21;
	   public static final int FUN_LEFTSOFT_PRESSED = 22;
	   public static final int FUN_RIGHTSOFT_PRESSED = 23;
	   public static final int FUN_SCREEN_WIDTH = 24;
	   public static final int FUN_SCREEN_HEIGHT = 25;


	   public static final int ACTION_DO_NOTHING = 0;
	   public static final int ACTION_SET_VARIABLE = 1;
	   public static final int ACTION_RANDOM_VARIABLE = 2;
	   public static final int ACTION_COMPUTE_VARIABLE = 3;
	   public static final int ACTION_IF_THEN_ELSE = 4;
	   public static final int ACTION_MOVE_VIEW = 5;
	   public static final int ACTION_SET_VIEWACTOR = 6;
	   public static final int ACTION_SET_PLAYERACTOR = 7;
	   public static final int ACTION_SET_ACTOR = 8;
	   public static final int ACTION_SET_ACTORACTION = 9;
	   public static final int ACTION_GET_ACTORACTION = 10;
	   public static final int ACTION_SET_ACTORPOSITION = 11;
	   public static final int ACTION_GET_ACTORPOSITION = 12;
	   public static final int ACTION_SET_ACTORFLAG = 13;
	   public static final int ACTION_GET_ACTORFLAG = 14;
	   public static final int ACTION_SET_ACTORPARAMETER = 15;
	   public static final int ACTION_GET_ACTORPARAMETER = 16;
	   public static final int ACTION_SET_ACTORDEST = 17;
	   public static final int ACTION_MOVE_ACTOR = 18;
	   public static final int ACTION_PLAY_ACTORACTION = 19;
	   public static final int ACTION_DELETE_ACTOR = 20;
	   public static final int ACTION_PLAY_TRAILER = 21;
	   public static final int ACTION_SHOW_DIALOG = 22;
	   public static final int ACTION_SHOW_MESSAGE = 23;
	   public static final int ACTION_SHOW_POEM = 24;
	   public static final int ACTION_FLASH_SCREEN = 25;
	   public static final int ACTION_SCREEN_FADEIN = 26;
	   public static final int ACTION_SCREEN_FADEOUT = 27;
	   public static final int ACTION_SCREEN_SHAKE = 28;
	   public static final int ACTION_SET_EFFECT_ON = 29;
	   public static final int ACTION_SET_EFFECT_OFF = 30;
	   public static final int ACTION_BREAK_TRIGGER = 31;
	   public static final int ACTION_SET_SOUND = 32;
	   public static final int ACTION_PLAY_SOUND = 33;
	   public static final int ACTION_SET_POSITION = 34;
	   public static final int ACTION_SWITCH_SCENE = 35;
	   public static final int ACTION_SHOW_INTERACT_DIALOG = 36;
}
